/*-----------------------------------------------------------------------
 * MediaFrame is an Open Source streaming media platform in Java 
 * which provides a fast, easy to implement and extremely small applet 
 * that enables to view your audio/video content without having 
 * to rely on external player applications or bulky plug-ins.
 *
 *-----------------------------------------------------------------------
 *
 * We changed a lot of code and added a lot of functionality.
 * This includes, but not limited to, the following changes:
 * 1. The project was renamed to MediaFrame;
 * 2. The connection speed detection procedure was added;
 * 3. The JavaScript API functions were added;
 * 4. The pre and post image support functionality was added;
 * 5. The ability to save movie into the local disk was added;
 * 6. The inner buffer for a movie file was added;
 * 7. The click-through functionality was added;    
 * 8. The .zip files support was added;    
 * 9. The realtime feedback agent functionality was added.    
 * For the full list of the current functionality please visit 
 * the following web page: http://mediaframe.org/
 *    
 * 06 Jul 2002 - 19 Dec 2004 Konstantin Belous, Oleg Lebedev
 *
 *-----------------------------------------------------------------------
 * 29/01/00		Initial version. mdm@techie.com
 *-----------------------------------------------------------------------
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

package mediaframe.mpeg1.audio.player;

import mediaframe.mpeg1.audio.decoder.*;

/**
 * The <code>AudioDevice</code> interface provides an abstraction for
 * a device capable of sounding audio samples. Samples are written to 
 * the device via the {@link AudioDevice#write write()} method. The device assumes
 * that these samples are signed 16-bit samples taken at the output frequency
 * of the decoder. If the decoder outputs more than one channel, the samples for
 * each channel are assumed to appear consecutively, with the lower numbered
 * channels preceeding higher-numbered channels. E.g. if there are two
 * channels, the samples will appear in this order:
 * <pre><code>
 * 
 *		l0, r0, l1, r1, l2, r2...
 * 
 * where<br/> 
 *	l<i>x</i> indicates the <i>x</i>th sample on channel 0
 *  r<i>x</i> indicates the <i>x</i>th sample on channel 1
 * </code></pre>
 *   
 * @since	0.0.8
 * @author	Mat McGowan
 */
public interface AudioDevice
{
	/**
	 * Prepares the AudioDevice for playback of audio samples.
	 * <p/> 
	 * If the audio device is already open, this method returns silently.
	 *  
	 * @param decoder	the decoder that will be providing the audio
	 *					samples. 
	 */
	public void open(Decoder decoder) throws JavaLayerException;
	
//	/**
//	 * Retrieves the open state of this audio device. 
//	 * 
//	 * @return <code>true</code> if this audio device is open and playing
//	 *			audio samples, or <code>false</code> otherwise. 
//	 */
//	public boolean isOpen();

	
	/**
	 * Writes audio data to this audio device. Audio data is
	 * assumed to be in the output format of the decoder. This
	 * method may return before the data has actually been sounded
	 * by the device if the device buffers audio samples.
	 * <p/>
	 * This method may return prior to the samples actually being played 
	 * by the audio device.
	 *  
	 * @param samples	the array of signed 16-bit samples to write
	 *					to the audio device. 
	 * @param offs		the offset of the first sample.
	 * @param len		the number of samples to write. 
	 * 
	 */
	public void write(short[] samples, int offs, int len) throws JavaLayerException;
		
	
	/**
	 * Closes this audio device. Any currently playing audio is stopped 
	 * as soon as possible. Any previously written audio data that has not been heard
	 * is discarded. 
	 * <p/>
	 * The implementation should ensure that any threads currently blocking
	 * on the device (e.g. during a <code>write</code> or <code>flush</code>
	 * operation should be unblocked by this method. 
	 */
	public void close();
	
	
	/**
	 * Blocks until all audio samples previously written to this audio device have
	 * been heard. 
	 */
	public void flush();
			
	/**
	 * Retrieves the current playback position in milliseconds. (-1 if not implemented).
	 */
//	public int getPosition();

	/**
	 * Retrieves the number of miliseconds left in buffer. (-1 if not implemented).
	 */
//	public int getBufferPosition();

	/**
	 * Returns fraction of output buffer consumed.
	 */
//	public float getFillRatio();


	/**
	 * Start player playing.
	 */
	public void play();

	/**
	 * Stop player playing.
	 */
	public void stop();


	/**
	 * Returns <tt>true</tt>, if the audio device is a crappy eight-bit eight khz ulaw decoder (browser).
	 */
	public boolean isEightBitEightKhzMuLaw();

	/**
	 * Sets the volume (in the range 0..1) of the audio playback. 
	 * @param volume the volume to set.
	 */
	public void setVolume(float volume);

	/**
	 * Set the mute state of the audio playback.
	 * @param mute the mute state (<tt>true</tt> if the mute on and the player doesn't play the audio). 
	 */
	public void setMute(boolean mute);

	/**
	 * Pause the Player. 
	 */
	public void pause();

	/**
	 * Is called if the end of file has been reached.
	 */
	public void endOfFile();
}
